
package com.pp.admin.common.server.entities;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Date;

import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;

import com.google.appengine.api.datastore.Key;
import com.pp.admin.common.server.CurrentThread;
import com.pp.admin.common.server.PersistenceManagerFactory;

public abstract class Base implements Serializable {
	
	/**
	 * 
	 */
	private static final long	serialVersionUID	= -1640034157619949258L;
	
	public static final byte	BOOLEAN_TRUE		= 1;
	
	public static final byte	BOOLEAN_FALSE		= 0;
	
	public Base() {

		if ( CurrentThread.getCurrentUser() != null ) {
			this.setCreatedBy( CurrentThread.getCurrentUser().getId() );
			this.setLastModefiedBy( CurrentThread.getCurrentUser().getId() );
		}
		this.setCreatedByTime( new Date() );
		this.setLastModefiedByTime( new Date() );
	}
	
	/**
	 * @return the createdBy
	 */
	public abstract User getCreatedBy();
	
	/**
	 * @param createdBy
	 *            the createdBy to set
	 */
	public abstract void setCreatedBy( Key createdBy );
	
	/**
	 * @return the createdByTime
	 */
	public abstract Date getCreatedByTime();
	
	/**
	 * @param createdByTime
	 *            the createdByTime to set
	 */
	public abstract void setCreatedByTime( Date createdByTime );
	
	/**
	 * @return the lastModefiedBy
	 */
	public abstract User getLastModefiedBy();
	
	/**
	 * @param lastModefiedBy
	 *            the lastModefiedBy to set
	 */
	public abstract void setLastModefiedBy( Key lastModefiedBy );
	
	/**
	 * @return the lastModefiedByTime
	 */
	public abstract Date getLastModefiedByTime();
	
	/**
	 * @param lastModefiedByTime
	 *            the lastModefiedByTime to set
	 */
	public abstract void setLastModefiedByTime( Date lastModefiedByTime );
	
	public void updateModifiedInfo() {

		this.setLastModefiedBy( CurrentThread.getCurrentUser().getId() );
		this.setLastModefiedByTime( new Date() );
		try {
			Field[] fields = this.getClass().getFields();
			for ( Field field : fields ) {
				Object obj = field.get( this );
				if ( obj instanceof Base ) {
					Base token = (Base) obj;
					token.updateModifiedInfo();
				}
			}
		} catch ( IllegalAccessException ex ) {
			ex.printStackTrace();
		}
	}
	
	public void update() {

		PersistenceManager pm = PersistenceManagerFactory.getPersistenceManager();
		try {
			update( pm );
		} finally {
			PersistenceManagerFactory.closePersistenceManager();
		}
	}
	
	public void update( PersistenceManager pm ) {

		updateModifiedInfo();
		Transaction tx = pm.currentTransaction();
		try {
			tx.begin();
			pm.makePersistent( this );
			tx.commit();
		} finally {
			if ( tx.isActive() ) {
				tx.rollback();
			}
		}
	}
	
	public void save() {

		PersistenceManager pm = PersistenceManagerFactory.getPersistenceManager();
		try {
			save( pm );
		} finally {
			PersistenceManagerFactory.closePersistenceManager();
		}
	}
	
	public void save( PersistenceManager pm ) {

		Transaction tx = pm.currentTransaction();
		try {
			tx.begin();
			pm.makePersistent( this );
			tx.commit();
		} finally {
			if ( tx.isActive() ) {
				tx.rollback();
			}
		}
	}
	
	public void delete() {

		PersistenceManager pm = PersistenceManagerFactory.getPersistenceManager();
		try {
			delete( pm );
		} finally {
			PersistenceManagerFactory.closePersistenceManager();
		}
	}
	
	public void delete( PersistenceManager pm ) {

		Transaction tx = pm.currentTransaction();
		try {
			tx.begin();
			pm.deletePersistent( this );
			tx.commit();
		} finally {
			if ( tx.isActive() ) {
				tx.rollback();
			}
		}
	}
}
